/**
 * 
 */
package net.penguinmenac3.archivedb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @author Michael
 * 
 */
class EntryLoader {
	private String folder = "db";
	private String filename = folder + "/archive";
	private int max_ID = -1;
	private String[] fulltextbuffer = null;
	private int fulltextbuffer_file = -1;

	SearchEntry[] getSearchEntries() {
		try {
			FileInputStream fis = new FileInputStream(filename + ".db");
			GZIPInputStream gzis = new GZIPInputStream(fis);
			ObjectInputStream in = new ObjectInputStream(gzis);
			SearchEntry[] vals = (SearchEntry[]) in.readObject();
			for (SearchEntry se : vals) {
				if (se.ID > max_ID) {
					max_ID = se.ID;
				}
			}
			return vals;
		} catch (Exception e) {
			try {
				File f = new File(folder);
				f.mkdirs();
				FileOutputStream fos = new FileOutputStream(filename + ".db");
				GZIPOutputStream gzos = new GZIPOutputStream(fos);
				ObjectOutputStream out = new ObjectOutputStream(gzos);
				out.writeObject(new SearchEntry[0]);
				out.flush();
				out.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		return new SearchEntry[0];
	}

	private int getFreeID() {
		max_ID++;
		return max_ID;
	}

	boolean addEntry(Entry e) {
		try {
			SearchEntry[] asearchentries = getSearchEntries();
			// write searchentry
			File f = new File(folder);
			f.mkdirs();
			FileOutputStream fos = new FileOutputStream(filename + ".db");
			GZIPOutputStream gzos = new GZIPOutputStream(fos);
			ObjectOutputStream out = new ObjectOutputStream(gzos);
			SearchEntry se = new SearchEntry(getFreeID(), e.filename,
					e.keywords, e.description, e.rating, e.local, e.filetype);
			LinkedList<SearchEntry> searchentries = new LinkedList<SearchEntry>();
			for (SearchEntry s : asearchentries) {
				searchentries.add(s);
			}
			searchentries.add(se);
			out.writeObject(searchentries.toArray(new SearchEntry[0]));
			out.flush();
			out.close();

			// write fulltext
			int postfix = (int) (se.ID / 100);
			int index = se.ID - (postfix * 100);

			String[] vals = null;
			if (fulltextbuffer_file == postfix) {
				vals = fulltextbuffer;
			} else if (new File(filename + "" + postfix + ".db").exists()) {
				FileInputStream fis = new FileInputStream(filename + ""
						+ postfix + ".db");
				GZIPInputStream gzis = new GZIPInputStream(fis);
				ObjectInputStream in = new ObjectInputStream(gzis);
				vals = (String[]) in.readObject();
			} else {
				vals = new String[100];
			}

			vals[index] = e.fulltext;
			fulltextbuffer = vals;
			fulltextbuffer_file = postfix;

			fos = new FileOutputStream(filename + "" + postfix + ".db");
			gzos = new GZIPOutputStream(fos);
			out = new ObjectOutputStream(gzos);

			out.writeObject(vals);
			out.flush();
			out.close();

			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
	}

	boolean deleteEntry(int id) {
		try {
			SearchEntry[] asearchentries = getSearchEntries();
			// write searchentry
			File f = new File(folder);
			f.mkdirs();
			FileOutputStream fos = new FileOutputStream(filename + ".db");
			GZIPOutputStream gzos = new GZIPOutputStream(fos);
			ObjectOutputStream out = new ObjectOutputStream(gzos);
			LinkedList<SearchEntry> searchentries = new LinkedList<SearchEntry>();
			for (SearchEntry s : asearchentries) {
				if (s.ID != id) {
					searchentries.add(s);
				}
			}
			out.writeObject(searchentries.toArray(new SearchEntry[0]));
			out.flush();
			out.close();

			// write fulltext
			int postfix = (int) (id / 100);
			int index = id - (postfix * 100);

			String[] vals = null;
			if (fulltextbuffer_file == postfix) {
				vals = fulltextbuffer;
			} else if (new File(filename + "" + postfix + ".db").exists()) {
				FileInputStream fis = new FileInputStream(filename + ""
						+ postfix + ".db");
				GZIPInputStream gzis = new GZIPInputStream(fis);
				ObjectInputStream in = new ObjectInputStream(gzis);
				vals = (String[]) in.readObject();
			} else {
				vals = new String[100];
			}

			vals[index] = "";
			fulltextbuffer = vals;
			fulltextbuffer_file = postfix;

			fos = new FileOutputStream(filename + "" + postfix + ".db");
			gzos = new GZIPOutputStream(fos);
			out = new ObjectOutputStream(gzos);

			out.writeObject(vals);
			out.flush();
			out.close();

			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
	}

	Entry completeEntry(SearchEntry se, double relevance, boolean b_fulltext) {
		String fulltext = "";

		// determine the file and the positon in it
		int postfix = (int) (se.ID / 100);
		int index = se.ID - (postfix * 100);

		if (b_fulltext) {
			try {
				if (fulltextbuffer_file == postfix) {
					fulltext = fulltextbuffer[index];
				} else {
					FileInputStream fis = new FileInputStream(filename + ""
							+ postfix + ".db");
					GZIPInputStream gzis = new GZIPInputStream(fis);
					ObjectInputStream in = new ObjectInputStream(gzis);
					String[] vals = (String[]) in.readObject();
					fulltext = vals[index];
					fulltextbuffer = vals;
					fulltextbuffer_file = postfix;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		Entry e = new Entry(se.ID, se.filename, se.keywords, se.description,
				se.rating, se.local, fulltext, relevance, se.filetype);
		return e;
	}

	Entry completeEntry(Entry se) {
		// determine the file and the positon in it
		int postfix = (int) (se.ID / 100);
		int index = se.ID - (postfix * 100);

		try {
			if (fulltextbuffer_file == postfix) {
				se.fulltext = fulltextbuffer[index];
			} else {
				FileInputStream fis = new FileInputStream(filename + ""
						+ postfix + ".db");
				GZIPInputStream gzis = new GZIPInputStream(fis);
				ObjectInputStream in = new ObjectInputStream(gzis);
				String[] vals = (String[]) in.readObject();
				se.fulltext = vals[index];
				fulltextbuffer = vals;
				fulltextbuffer_file = postfix;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return se;
	}

}
